#ifndef _GORBATRAS_FBXJSONEXPORTER
#define _GORBATRAS_FBXJSONEXPORTER

#include "Gorbatras_Library.h"

namespace GC
{	
	class FbxJsonExporter
	{
		public:					
			/// <summary>
			/// If it's either [] or {}
			/// </summary>
			enum KeyContainerType
			{		
				/// <summary>
				/// [ ]
				/// </summary>
				Brackets = 0,				
				/// <summary>
				/// { }
				/// </summary>
				Braces = 1
				
			};
			
			FbxJsonExporter(const bool a_prettify = false);
			const bool Export(const FbxData* a_data, const _TCHAR* a_outputName);	

			/// <summary>
			/// The amount of items in AddKeyValuePairArray there can be per row in a pretty json print before new line
			/// </summary>
			static const int ITEMS_PER_ROW = 70;
			/// <summary>
			/// The amount of keyframe values there can be in a pretty json print before new line
			/// </summary>
			static const int KEYFRAMES_PER_ROW = 12;
		private:		
			/// <summary>
			/// The m_prettify variable used by the Add... Functions
			/// This variable is not constant because for example ExportAnimationChannel sets it to false when adding the keyframe values
			/// </summary>
			bool m_prettify;
			/// <summary>
			/// How many tabs when m_prettify is true to use in PrintNewLine
			/// </summary>
			int m_tabCount;
			/// <summary>
			/// The output string to be written to a file
			/// </summary>
			FbxString m_output;
			//Writes the metadata information
			void ExportMetadata(const FbxData* a_data, std::wofstream& a_filestream);
			//Loops through all meshes to export them
			void ExportMeshes(const FbxData* a_data, std::wofstream& a_filestream);
			//Exports an individual mesh
			void ExportMesh(const FbxMesh* a_mesh);
			//Exports all the bones
			void ExportBones(const FbxMesh* a_bone);
			//Logic for exporting an individual bone
			void ExportBone(const FbxBone* a_bone, const bool a_addComma);
			//Exports all the skeletons
			void ExportSkeletons(const FbxData* a_data, std::wofstream& a_filestream);
			void ExportSkeleton(const FbxSkeleton* a_skeleton, const bool a_addComma);
			//Exports all the animation data
			void ExportAnimations(const FbxData* a_data, std::wofstream& a_filestream);
			void ExportAnimation(const FbxAnimation* a_animation, const bool a_addComma);
			void ExportAnimationLayer(const FbxAnimationLayer* a_layer, const bool a_addComma);
			void ExportAnimationNode(const FbxAnimationNode* a_node, const bool a_addComma);
			void ExportAnimationChannels(const FbxAnimationTransform* a_transform);
			void ExportAnimationTransform(const int a_keyCount, const char* a_keyName, const FbxAnimationTransformKey& a_keyValues, const int a_frameValueLength, const bool a_addComma);
			//Writes m_output to file and clears the output
			void PrintOutput(std::wofstream& a_filestream);
			//Adds tabCount amount of tabs to output
			void AddTabString();
			//Adds a new line to output and then automatically sets the tabs aswell
			void AddNewLine();			
			//Add a stringed variable to output, example: meshes --> \"meshes\"   
			//Or if a_isKey = true:  metadata --> \"metadata\": 
			template<typename T>
			//void AddStringValue(const char* a_value, const bool a_isKey = false);
			void AddStringValue(T a_value, const bool a_isKey = false);
			//Adds a key value pair of int or double
			template<typename T>
			void AddKeyValuePair(const char* a_key, const T a_value, const bool a_stringify = false, const bool a_addComma = true);
			
			//Adds a key value pair of array number
			template<typename T>
			void AddKeyValuePairArray(const char* a_key, const T a_values, const int a_count, const bool a_addComma = true);
			//Adds a group and increases tabCount by 1			
			void OpenKey(const char* a_key, const KeyContainerType a_container);
			
			void CloseKey(const KeyContainerType a_containerType, const bool a_addComma = false);

			void IncreaseTabCount();
			void DecreaseTabCount();

	};
}

#endif